
#
# Author : itech
# 

import optparse
import sys
import subprocess
import os
import time
import stat


# ---------------------------------------------------------------------------- #
SIGNTOOL = r'C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\signtool.exe'
USAGE = "usage: %prog [options] keyfile password|dummy"
TIME_SERVER = r'http://timestamp.verisign.com/scripts/timstamp.dll' 
# ---------------------------------------------------------------------------- #


def main():

    p = optparse.OptionParser(
        description="Digitally signs a list of files",
        prog='signer',
        version='%prog 0.0.1',
        usage=USAGE
        )

    p.add_option('-t','--timestamp',action='store',type="string",
        dest='time_server')
    p.add_option('-s','--signfile',action='store',type="string",
        dest='sign_file')
    p.add_option('-r','--root',action='store',type="string",
        dest='root')
    p.add_option('-p','--passfile',action='store',type="string",
        dest='passfile')

    options, arguments = p.parse_args()
    if len(arguments) != 2:
        p.error("not enough arguments => add dummy password if using a passfile")

    if options.sign_file:
        sign_file = options.sign_file
    else:
        sign_file = "signme.txt"

    if options.root:
        path = options.root
    else:
        path = os.getcwd()
        
    if options.time_server:
        time_server = options.time_server
    else:
        time_server = TIME_SERVER        

    key = arguments[0]
    password = arguments[1]

    if options.passfile:
        fd = open(options.passfile)
        password = fd.read().strip()
        fd.close()


    ret = process_files(path,sign_file,key,password,time_server)
    if ret != 0:
        sys.stderr.write("Something went wrong during the signing process.\n")
    sys.exit(ret)


def get_files(top_level):
    for root, dirs, files in os.walk(top_level):
        for name in files:
            yield os.path.abspath(os.path.join(root, name))

def sign(key,password,time_server,path):
    params = [SIGNTOOL, r'sign', r'/f', key, r'/p', password,
        r'/v', r'/t', time_server, path]
    cmd = subprocess.list2cmdline(params)
    return subprocess.call(cmd)

def load_endings(string_list):
    endings = set()
    for file_ in file(string_list).readlines():
        pattern = file_.strip()
        if pattern != "":
            endings.add(pattern)
    return endings


def process_files(top_level,string_list,key,password,time_server):
    file_endings = load_endings(string_list)
    ret = 0
    for path in get_files(top_level):
        for ending in file_endings:
            if path.endswith(ending):
                if not os.access(path,os.W_OK):
                    os.chmod(path,stat.S_IWRITE)
                ret = sign(key,password,time_server,path)
                if ret != 0:
                    return ret
    return ret



if __name__ == "__main__":
    main()